#region Using

using System;
using System.Xml;
using System.IO;
using System.Globalization;
using System.Collections.Generic;
using System.Collections.Specialized;
using BlogEngine.Core;

#endregion

namespace BlogEngine.Core.Providers
{
	/// <summary>
	/// A storage provider for BlogEngine that uses XML files.
	/// <remarks>
	/// To build another provider, you can just copy and modify
	/// this one. Then add it to the web.config's BlogEngine section.
	/// </remarks>
	/// </summary>
	public partial class XmlBlogProvider : BlogProviderBase
	{

		#region Links

		/// <summary>
		/// Gets a Link based on a Guid
		/// </summary>
		/// <param name="id">The Links's Guid.</param>
		/// <returns>A matching Link</returns>
		public override Link SelectLink(Guid id)
		{
			Link newLink = new Link();

			foreach (Link link in Link.Items)
			{
				if (link.Id == id)
					newLink = link;
			}
			newLink.MarkOld();
			return newLink;
		}

		/// <summary>
		/// Inserts a Link
		/// </summary>
		/// <param name="link">Must be a valid Link object.</param>
		public override void InsertLink(Link link)
		{
			Link.Items.Add(link);
			Link.Items.Sort();
			RewriteLinkFile(Link.Items);
		}

		/// <summary>
		/// Updates the link.
		/// </summary>
		/// <param name="link">The link.</param>
		public override void UpdateLink(Link link)
		{
			if (!Link.Items.Contains(link))
				Link.Items.Add(link);

			Link.Items.Sort();

			RewriteLinkFile(Link.Items);
		}

		/// <summary>
		/// Deletes a Link
		/// </summary>
		/// <param name="link">Must be a valid Link object.</param>
		public override void DeleteLink(Link link)
		{
			List<Link> links = Link.Items;

			if (links.Contains(link))
				links.Remove(link);

			RewriteLinkFile(links);
		}

		private void RewriteLinkFile(List<Link> links)
		{
			string fileName = _Folder + "links.xml";

			if (File.Exists(fileName))
				File.Delete(fileName);

			using (XmlTextWriter writer = new XmlTextWriter(fileName, System.Text.Encoding.UTF8))
			{
				writer.Formatting = Formatting.Indented;
				writer.Indentation = 4;
				writer.WriteStartDocument(true);
				writer.WriteStartElement("links");

				foreach (Link link in links)
				{
					writer.WriteStartElement("link");
					writer.WriteAttributeString("id", link.Id.ToString());
					writer.WriteAttributeString("description", link.Description);
					writer.WriteAttributeString("website", link.Website);
					writer.WriteAttributeString("feed", link.Feed);
					writer.WriteAttributeString("XFNTag", link.XFNTag);
					writer.WriteAttributeString("image", link.Image);
					writer.WriteAttributeString("blogroll", link.BlogRoll.ToString());
					writer.WriteAttributeString("isPublished", link.IsPublished.ToString());
					writer.WriteAttributeString("slug", link.Slug);
					writer.WriteAttributeString("order", link.Order.ToString());
					writer.WriteValue(link.Title);
					writer.WriteEndElement();
					link.MarkOld();
				}

				writer.WriteEndElement();
			}
		}

		/// <summary>
		/// Fills an unsorted list of categories.
		/// </summary>
		/// <returns>A List&lt;Link&gt; of all Links.</returns>
		public override List<Link> FillLinks()
		{
			List<Link> links = new List<Link>();
			string fileName = _Folder + "links.xml";

			if (!File.Exists(fileName))
				return links;

			XmlDocument doc = new XmlDocument();
			doc.Load(fileName);

			foreach (XmlNode node in doc.SelectNodes("links/link"))
			{
				Link link = new Link();

				link.Id = new Guid(node.Attributes["id"].InnerText);
				link.Title = node.InnerText;
				if (node.Attributes["description"] != null)
					link.Description = node.Attributes["description"].InnerText;
				if (node.Attributes["slug"] != null)
					link.Slug = node.Attributes["slug"].InnerText;
				if (node.Attributes["XFNTag"] != null)
					link.XFNTag = node.Attributes["XFNTag"].InnerText;
				if (node.Attributes["website"] != null)
					link.Website = node.Attributes["website"].InnerText;
				if (node.Attributes["feed"] != null)
					link.Feed = node.Attributes["feed"].InnerText;
				if (node.Attributes["image"] != null)
					link.Image = node.Attributes["image"].InnerText;
				if (node.Attributes["blogroll"] != null)
					link.BlogRoll = bool.Parse(node.Attributes["blogroll"].InnerText);
				if (node.Attributes["isPublished"] != null)
					link.IsPublished = bool.Parse(node.Attributes["isPublished"].InnerText);
				if (node.Attributes["order"] != null)
					link.Order = Convert.ToInt32(node.Attributes["order"].InnerText);

				links.Add(link);
				link.MarkOld();
			}

			return links;
		}

		#endregion

	}
}
